import tkinter as tk
from math import ceil
import ttkbootstrap as ttk
from ttkbootstrap.constants import *
from tksheet import Sheet
import os
from PIL import Image, ImageTk
from utils import resource_path, log_info, log_error, log_exception, log_debug

from services import QuestionsBankService
from configs.config import WINDOW_CONFIG, THEME_CONFIG


class QuestionsBankView:
    def __init__(self, root):
        self.root = root
        
        # 只在root是顶级窗口时设置标题和大小
        if hasattr(root, 'title'):
            self.root.title("题库管理系统")
        if hasattr(root, 'geometry'):
            width = WINDOW_CONFIG['questions_bank']['width']
            height = WINDOW_CONFIG['questions_bank']['height']
            self.root.geometry(f"{width}x{height}")
        
        # 初始化图片窗口引用
        self.image_window = None
        
        # 定义自定义tooltip样式
        # 使用ttkbootstrap的ToolTip组件替代ttksheet内置tooltip
        from ttkbootstrap.tooltip import ToolTip
        
        # 设置主窗口背景
        try:
            self.root.configure(bg='#1e1e1e')
        except tk.TclError:
            # 如果root是Frame而不是Toplevel，可能没有bg属性
            pass
        
        # 主题颜色（使用配置文件中的颜色）
        self.bg_color = THEME_CONFIG['bg_color']  # 深灰背景
        self.fg_color = THEME_CONFIG['fg_color']  # 浅灰前景
        self.header_bg = THEME_CONFIG['header_bg']  # 表头背景
        self.header_fg = THEME_CONFIG['header_fg']  # 表头文字
        self.grid_color = THEME_CONFIG['grid_color']  # 网格线
        self.highlight_color = THEME_CONFIG['highlight_color']  # 选中行高亮
        self.alt_row_color = THEME_CONFIG['alt_row_color']  # 交替行颜色
        self.warning_color = THEME_CONFIG['warning_color']  # 警告颜色
        self.success_color = THEME_CONFIG['success_color']  # 成功颜色
        self.tooltip_bg_color = THEME_CONFIG['tooltip_bg_color']  # 提示框背景色
        self.tooltip_fg_color = THEME_CONFIG['tooltip_fg_color']  # 提示框前景色
        
        # 初始化服务层
        self.service = QuestionsBankService()
        
        # 页面配置
        self.page_size = 15
        self.current_page = 1
        self.total_pages = 0
        self.total_records = 0
        self.search_query = ""
        
        # 列宽配置 - 根据题库数据调整
        self.column_widths = [90, 320, 100, 100, 100, 100, 100, 100, 50, 50, 50, 80]
        
        # 创建UI
        self.create_widgets()
        
        # 加载表结构
        self.load_table_structure()
        
        # 加载第一页数据
        self.load_page_data()

    def create_widgets(self):
        """创建界面组件"""
        # 顶部控制面板
        control_frame = ttk.Frame(self.root, padding=(15, 15, 15, 10))
        control_frame.pack(fill=tk.X)
        
        # 搜索框
        ttk.Label(control_frame, text="搜索:").grid(row=1, column=0, padx=(0, 5))
        self.search_var = tk.StringVar()
        search_entry = ttk.Entry(
            control_frame, 
            textvariable=self.search_var, 
            width=30,
            bootstyle="light"
        )
        search_entry.grid(row=1, column=1, padx=5)
        search_entry.bind("<Return>", self.search_data)
        
        # 搜索图片按钮
        # 加载搜索图标
        search_icon_path = resource_path(os.path.join("icon", "search.png"))
        if os.path.exists(search_icon_path):
            search_img = Image.open(search_icon_path)
            search_img = search_img.resize((25, 25), Image.Resampling.LANCZOS)
            search_photo = ImageTk.PhotoImage(search_img)
        else:
            search_photo = None

        search_button = ttk.Label(
            control_frame, 
            image=search_photo, 
            cursor="hand2"
        )
        search_button.grid(row=1, column=2, padx=5)
        search_button.bind("<Button-1>", lambda e: self.search_data())
        # 保存引用以防止图片被垃圾回收
        control_frame.search_photo = search_photo

        # 重置图片按钮
        # 加载重置图标
        reset_icon_path = resource_path(os.path.join("icon", "reset.png"))
        if os.path.exists(reset_icon_path):
            reset_img = Image.open(reset_icon_path)
            reset_img = reset_img.resize((25, 25), Image.Resampling.LANCZOS)
            reset_photo = ImageTk.PhotoImage(reset_img)
        else:
            reset_photo = None

        reset_button = ttk.Label(
            control_frame, 
            image=reset_photo, 
            cursor="hand2"
        )
        reset_button.grid(row=1, column=3, padx=5)
        reset_button.bind("<Button-1>", lambda e: self.reset_search())
        # 保存引用以防止图片被垃圾回收
        control_frame.reset_photo = reset_photo

        # 添加分类筛选
        filter_label = ttk.Label(control_frame, text="分类筛选:")
        filter_label.grid(row=1, column=4, padx=(15, 5))
        filter_label.lift()  # 确保标签在最上层

        # 创建一个专门用于分类筛选的框架
        filter_frame = ttk.Frame(control_frame)
        filter_frame.grid(row=1, column=5, columnspan=3, padx=5, sticky="w")
        filter_frame.lift()  # 确保框架在最上层

        # A类复选框
        self.filter_la = tk.BooleanVar(value=False)
        la_check = ttk.Checkbutton(filter_frame, text="A类", variable=self.filter_la)
        la_check.pack(side=tk.LEFT, padx=5)
        la_check.configure(state="normal")
        log_debug(f"A类复选框状态: {la_check.cget('state')}")  # 调试信息
        # 添加变量变化跟踪
        self.filter_la.trace_add("write", lambda *args: [log_debug(f"A类筛选状态变更为: {self.filter_la.get()}"), self.search_data()])

        # B类复选框
        self.filter_lb = tk.BooleanVar(value=False)
        lb_check = ttk.Checkbutton(filter_frame, text="B类", variable=self.filter_lb)
        lb_check.pack(side=tk.LEFT, padx=5)
        lb_check.configure(state="normal")
        log_debug(f"B类复选框状态: {lb_check.cget('state')}")  # 调试信息
        # 添加变量变化跟踪
        self.filter_lb.trace_add("write", lambda *args: [log_debug(f"B类筛选状态变更为: {self.filter_lb.get()}"), self.search_data()])

        # C类复选框
        self.filter_lc = tk.BooleanVar(value=False)
        lc_check = ttk.Checkbutton(filter_frame, text="C类", variable=self.filter_lc)
        lc_check.pack(side=tk.LEFT, padx=5)
        lc_check.configure(state="normal")
        log_debug(f"C类复选框状态: {lc_check.cget('state')}")  # 调试信息
        # 添加变量变化跟踪
        self.filter_lc.trace_add("write", lambda *args: [log_debug(f"C类筛选状态变更为: {self.filter_lc.get()}"), self.search_data()])

        # 确保所有组件可见
        filter_frame.lift()
        la_check.lift()
        lb_check.lift()
        lc_check.lift()
        
        # 表格框架
        # 增加右侧边距至20像素
        # 增加右侧边距至30像素
        self.table_frame = ttk.Frame(self.root, padding=(10, 10, 30, 10))
        self.table_frame.pack(fill=tk.BOTH, expand=True, pady=(0, 10))
        
        # 创建TkSheet表格并应用深色主题
        self.sheet = Sheet(
            self.table_frame,
            height=470,
            show_row_index=False,
            show_x_scrollbar=True,
            show_y_scrollbar=True,
            headers=self.get_empty_headers(),
            empty_vertical=0,
            empty_horizontal=0,
            align="w",
            header_align="center",
            header_height=29,
            row_height=29,
            set_all_cell_sizes_on_display=True,
            # 禁用ttksheet内置tooltip，使用ttkbootstrap的ToolTip
            tooltips=False,
            # 深色主题配置
            table_bg=self.bg_color,  # 表格背景
            table_fg=self.fg_color,  # 表格文字
            table_grid_fg=self.grid_color,  # 网格线颜色
            index_bg=self.header_bg,  # 行索引背景
            index_fg=self.fg_color,  # 行索引文字
            index_grid_fg=self.grid_color,  # 行索引网格线
            index_selected_cells_bg=self.highlight_color,  # 选中行索引背景
            header_bg=self.header_bg,  # 表头背景
            header_fg=self.header_fg,  # 表头文字
            header_grid_fg=self.grid_color,  # 表头网格线
            header_selected_cells_bg=self.highlight_color,  # 选中表头背景
            selected_rows_bg=self.highlight_color,  # 选中行背景
            selected_rows_fg=self.fg_color,  # 选中行文字
            selected_columns_bg=self.highlight_color,  # 选中列背景
            selected_cells_bg=self.highlight_color,  # 选中单元格背景
            selected_cells_fg=self.fg_color,  # 选中单元格文字
            top_left_bg=self.header_bg,  # 左上角单元格背景
            top_left_fg=self.fg_color,  # 左上角单元格文字
            top_left_grid_fg=self.grid_color  # 左上角网格线
        )

        # 监听框架大小变化，动态调整列宽
        self.table_frame.bind('<Configure>', lambda e: self.set_column_widths())
        
        # 设置表格样式 - 禁用列宽调整
        self.sheet.enable_bindings(
            "single_select",
            "drag_select",
            "column_select",
            "row_select",
            "arrowkeys",
            "right_click_popup_menu",
            "copy",
        )
        
        # 禁用行高调整
        # self.sheet.row_height_configure(fixed=True)
        
        # 添加自定义悬停事件，使用ttkbootstrap的ToolTip
        self.sheet.bind("<Motion>", self.on_cell_hover)
        # 添加图片列点击事件
        self.sheet.bind("<Button-1>", self.on_cell_click)
        # 添加双击行编辑事件
        self.sheet.bind("<Double-1>", self.on_row_double_click)
        # 添加鼠标离开表格事件处理
        self.sheet.bind("<Leave>", lambda e: self.hide_tooltip())
        # 确保表格在最上层
        self.sheet.lift()
        self.tooltip = None
        
        # 配置网格样式
        self.sheet.grid(row=0, column=0, sticky="nswe", padx=5, pady=5)

        # 初始化列宽
        self.set_column_widths()
        
        # 底部框架：包含分页导航和数据信息
        bottom_frame = ttk.Frame(self.table_frame)
        bottom_frame.grid(row=1, column=0, sticky="e")

        # 创建一个容器框架来水平排列所有元素
        container_frame = ttk.Frame(bottom_frame)
        container_frame.pack(side=tk.RIGHT, padx=10, fill=tk.X, expand=True)

        # 1. 每页显示数量
        page_size_frame = ttk.Frame(container_frame)
        page_size_frame.pack(side=tk.LEFT, padx=(0, 10))
        
        ttk.Label(page_size_frame, text="", font=('SimHei', 12)).grid(row=0, column=0, padx=(0, 5))
        self.page_size_var = tk.StringVar(value=str(self.page_size))
        page_sizes = ttk.Combobox(
            page_size_frame, 
            width=3, 
            textvariable=self.page_size_var
        )
        page_sizes['values'] = (15, 30, 50, 100)
        page_sizes.grid(row=0, column=1, padx=5)
        page_sizes.bind("<<ComboboxSelected>>", self.change_page_size)
        
        # 2. 页码输入和跳转
        page_input_frame = ttk.Frame(container_frame)
        page_input_frame.pack(side=tk.LEFT, padx=(0, 10))
        
        ttk.Label(page_input_frame, text="", font=('SimHei', 12)).grid(row=0, column=0, padx=(0, 5))
        self.page_entry = ttk.Entry(page_input_frame, width=3)
        self.page_entry.grid(row=0, column=1, padx=5)
        self.page_entry.insert(0, "1")
        self.page_entry.bind("<Return>", self.go_to_page)
        
        ttk.Label(page_input_frame, text="/", font=('SimHei', 12)).grid(row=0, column=2, padx=5)
        self.total_pages_label = ttk.Label(page_input_frame, text="1", font=('SimHei', 12))
        self.total_pages_label.grid(row=0, column=3, padx=5)
        
        
        # 3. 总记录数信息
        self.total_records_var = tk.StringVar(value="共 0 条数据")
        records_label = ttk.Label(
            container_frame, 
            textvariable=self.total_records_var, 
            font=('SimHei', 12)
        )
        records_label.pack(side=tk.LEFT, padx=(0, 10))
        
        # 首页和上一页按钮
        prev_buttons_frame = ttk.Frame(container_frame)
        prev_buttons_frame.pack(side=tk.LEFT, padx=(0, 5))
        
        # 5. 页码列表
        self.pages_frame = ttk.Frame(container_frame)
        self.pages_frame.pack(side=tk.LEFT, padx=(0, 5))
        
        # 6. 下一页和末页按钮
        next_buttons_frame = ttk.Frame(container_frame)
        next_buttons_frame.pack(side=tk.LEFT, padx=(0, 5))
        
        # 首页图片标签
        # 加载图标
        icon_path = resource_path(os.path.join("icon", "page_start.png"))
        if os.path.exists(icon_path):
            icon_img = Image.open(icon_path)
            icon_img = icon_img.resize((25, 25), Image.Resampling.LANCZOS)
            first_page_img = ImageTk.PhotoImage(icon_img)
        else:
            first_page_img = None

        first_page_label = ttk.Label(
            prev_buttons_frame, 
            image=first_page_img, 
            cursor="hand2"
        )
        first_page_label.grid(row=0, column=0, padx=2)
        first_page_label.bind("<Button-1>", lambda e: self.first_page())
        # 保存引用以防止图片被垃圾回收
        prev_buttons_frame.first_page_img = first_page_img
        
        # 上一页图片标签
        # 加载图标
        icon_path = resource_path(os.path.join("icon", "page_pre.png"))
        if os.path.exists(icon_path):
            icon_img = Image.open(icon_path)
            icon_img = icon_img.resize((25, 25), Image.Resampling.LANCZOS)
            prev_page_img = ImageTk.PhotoImage(icon_img)
        else:
            prev_page_img = None

        prev_page_label = ttk.Label(
            prev_buttons_frame, 
            image=prev_page_img, 
            cursor="hand2"
        )
        prev_page_label.grid(row=0, column=1, padx=2)
        prev_page_label.bind("<Button-1>", lambda e: self.prev_page())
        # 保存引用以防止图片被垃圾回收
        prev_buttons_frame.prev_page_img = prev_page_img
        
        # 下一页图片标签
        # 加载图标
        icon_path = resource_path(os.path.join("icon", "page_next.png"))
        if os.path.exists(icon_path):
            icon_img = Image.open(icon_path)
            icon_img = icon_img.resize((25, 25), Image.Resampling.LANCZOS)
            next_page_img = ImageTk.PhotoImage(icon_img)
        else:
            next_page_img = None

        next_page_label = ttk.Label(
            next_buttons_frame, 
            image=next_page_img, 
            cursor="hand2"
        )
        next_page_label.grid(row=0, column=0, padx=2)
        next_page_label.bind("<Button-1>", lambda e: self.next_page())
        # 保存引用以防止图片被垃圾回收
        next_buttons_frame.next_page_img = next_page_img
        
        # 末页图片标签
        # 加载图标
        icon_path = resource_path(os.path.join("icon", "page_end.png"))
        if os.path.exists(icon_path):
            icon_img = Image.open(icon_path)
            icon_img = icon_img.resize((25, 25), Image.Resampling.LANCZOS)
            last_page_img = ImageTk.PhotoImage(icon_img)
        else:
            last_page_img = None

        last_page_label = ttk.Label(
            next_buttons_frame, 
            image=last_page_img, 
            cursor="hand2"
        )
        last_page_label.grid(row=0, column=1, padx=2)
        last_page_label.bind("<Button-1>", lambda e: self.last_page())
        # 保存引用以防止图片被垃圾回收
        next_buttons_frame.last_page_img = last_page_img
    
    def get_empty_headers(self):
        """返回题目表格表头"""
        return ["ID", "题目", "选项A", "选项B", "选项C", "选项D", "正确答案", "类型", "A类", "B类", "C类", "图片"]

    def load_table_structure(self):
        """加载表结构"""
        # 直接设置列名，无需从数据库查询
        self.columns = ['id', 'Q', 'A', 'B', 'C', 'D', 'T', 'type', 'LA', 'LB', 'LC', 'F']
        
        # 从服务层获取总记录数
        try:
            self.total_records = self.service.get_filtered_records_count()
            self.total_pages = ceil(self.total_records / self.page_size)
            self.total_pages_label.config(text=str(self.total_pages))
            self.total_records_var.set(f"共 {self.total_records} 题")
        except Exception as e:
            log_error(f"加载数据总数失败: {str(e)}")
            self.show_warning("错误", f"加载数据总数失败: {str(e)}")
            
            # 获取总记录数
            cursor.execute("SELECT COUNT(*) FROM questions")
            self.total_records = cursor.fetchone()[0]
            self.total_pages = ceil(self.total_records / self.page_size)
        
        # 更新UI
        self.total_pages_label.config(text=str(self.total_pages))
        self.total_records_var.set(f"共 {self.total_records} 题")
        self.update_page_buttons()
        

    def on_cell_hover(self, event):
        # 使用Toplevel窗口创建自定义tooltip
        # print("鼠标悬停事件触发")

        region = self.sheet.identify_region(event)
        row = self.sheet.identify_row(event)
        col = self.sheet.identify_column(event)
        # print(f"当前鼠标位置: 区域={region}, 行={row}, 列={col}")

        # 重置鼠标指针
        self.sheet.configure(cursor="arrow")

        # 如果鼠标不在表格区域，隐藏tooltip
        if region != "table":
            self.hide_tooltip()
            return

        # 检查行列是否有效
        if row is None or col is None or not hasattr(self, 'original_data') or not hasattr(self, 'truncated_cells'):
            self.hide_tooltip()
            return

        # 检查是否在图片列(第11列，索引从0开始)
        if col == 11 and hasattr(self, 'image_data'):
            # 检查是否有图片数据
            if row < len(self.image_data) and self.image_data[row] and isinstance(self.image_data[row], str) and self.image_data[row].startswith('data:image/'):
                # 设置手型鼠标指针
                self.sheet.configure(cursor="hand2")

        tooltip_text = None
        show_tooltip = False

        # 只有当鼠标在表格区域且有有效行列时才考虑显示tooltip
        if 0 <= row < len(self.original_data) and 0 <= col < len(self.original_data[0]):
            # 检查单元格是否被截断
            if (row, col) in self.truncated_cells:
                # 使用原始数据作为tooltip内容
                tooltip_text = str(self.original_data[row][col])
                show_tooltip = True
        else:
            # 无效行列，隐藏tooltip
            self.hide_tooltip()
            return

        # 如果不需要显示tooltip，隐藏它并返回
        if not show_tooltip or not tooltip_text:
            # 取消定时器并隐藏tooltip
            try:
                self.root.after_cancel(self.show_tooltip_timer)
                self.root.after_cancel(self.tooltip_timer)
                if hasattr(self, 'custom_tooltip'):
                    self.custom_tooltip.withdraw()
            except:
                pass
            return

        # 如果tooltip已存在，更新位置和内容
        if hasattr(self, 'custom_tooltip'):
            try:
                # 更新内容
                label = self.custom_tooltip.winfo_children()[0]
                # 计算表格右侧位置
                table_right = self.sheet.winfo_rootx() + self.sheet.winfo_width()
                mouse_x = self.root.winfo_pointerx()
                max_width = table_right - mouse_x - 10  # 10px边距
                
                label.config(
                    text=tooltip_text,
                    wraplength=max_width if max_width > 100 else 200  # 最小宽度200px
                )
                # 更新位置
                x = mouse_x + 10
                y = self.root.winfo_pointery() + 10
                self.custom_tooltip.geometry(f"+{x}+{y}")
                # 确保tooltip可见 - 但先不显示，由定时器控制
                self.custom_tooltip.withdraw()
                # print("已更新自定义tooltip")
            except Exception as e:
                log_exception(f"更新自定义tooltip失败: {e}")
                
        else:
            # 创建新的自定义tooltip
            try:
                self.custom_tooltip = tk.Toplevel(self.root)
                # 配置tooltip样式
                self.custom_tooltip.configure(
                    bg=self.tooltip_bg_color,
                    bd=1,  # 细边框
                    relief='solid',
                    highlightthickness=0
                )
                # 移除标题栏
                self.custom_tooltip.overrideredirect(True)
                # 添加标签显示文本
                # 计算表格右侧位置
                table_right = self.sheet.winfo_rootx() + self.sheet.winfo_width()
                mouse_x = self.root.winfo_pointerx()
                max_width = table_right - mouse_x - 10  # 10px边距
                
                label = ttk.Label(
                    self.custom_tooltip,
                    text=tooltip_text,
                    foreground=self.tooltip_fg_color,
                    background=self.tooltip_bg_color,
                    borderwidth=1,
                    relief='solid',
                    font=('微软雅黑', 10, 'normal'),
                    padding=5,
                    justify='left',
                    wraplength=max_width if max_width > 100 else 200  # 最小宽度200px
                )
                label.pack()
                # 设置位置
                x = mouse_x + 10
                y = self.root.winfo_pointery() + 10
                self.custom_tooltip.geometry(f"+{x}+{y}")
                # 初始隐藏，由定时器控制显示
                self.custom_tooltip.withdraw()
                # print("已创建自定义tooltip")
            except Exception as e:
                log_exception(f"创建自定义tooltip失败: {e}")
        
        # 鼠标悬停延迟显示tooltip
        try:
            # 取消之前的显示和隐藏定时器
            self.root.after_cancel(self.show_tooltip_timer)
            self.root.after_cancel(self.tooltip_timer)
        except:
            pass
        
        # 设置显示延迟（1000毫秒）
        self.show_tooltip_timer = self.root.after(1000, self.show_tooltip)
        
        # 设置隐藏定时器（2秒后隐藏）
        self.tooltip_timer = self.root.after(30000, self.hide_tooltip)
    

    
    def show_tooltip(self):
        # 显示tooltip
        if hasattr(self, 'custom_tooltip'):
            try:
                self.custom_tooltip.deiconify()
                # print("已显示tooltip")
            except Exception as e:
                log_exception(f"显示tooltip失败: {e}")
                
    def hide_tooltip(self):
        # 隐藏tooltip并取消所有相关定时器
        if hasattr(self, 'custom_tooltip'):
            try:
                self.custom_tooltip.withdraw()
                # 取消显示和隐藏定时器
                try:
                    self.root.after_cancel(self.show_tooltip_timer)
                    self.root.after_cancel(self.tooltip_timer)
                except:
                    pass
                # print("已隐藏tooltip")
            except Exception as e:
                log_exception(f"隐藏tooltip失败: {e}")
    
    def load_page_data(self):
        """加载当前页题目数据"""
        try:
            # 获取筛选条件
            filter_la = hasattr(self, 'filter_la') and self.filter_la.get()
            filter_lb = hasattr(self, 'filter_lb') and self.filter_lb.get()
            filter_lc = hasattr(self, 'filter_lc') and self.filter_lc.get()
            
            # 调用服务层获取分页数据
            rows = self.service.get_page_data(self.current_page, self.page_size, self.search_query, filter_la, filter_lb, filter_lc)
            
            # 调用服务层获取总记录数
            self.total_records = self.service.get_filtered_records_count(self.search_query, filter_la, filter_lb, filter_lc)
            self.total_pages = ceil(self.total_records / self.page_size)
            self.total_records_var.set(f"共 {self.total_records} 题")
            
            # 转换为二维列表格式（TkSheet需要的数据格式）
            data = []
            original_data = []  # 存储原始数据用于tooltip
            self.image_data = []  # 存储图片数据
            
            for row in rows:
                row_data = []
                original_row = []
                # 按顺序添加id, Q, A, B, C, D, T, type, LA, LB, LC, F
                row_data.append(row['id'])
                original_row.append(row['id'])
                
                row_data.append(row['Q'])
                original_row.append(row['Q'])
                
                row_data.append(row['A'])
                original_row.append(row['A'])
                
                row_data.append(row['B'])
                original_row.append(row['B'])
                
                row_data.append(row['C'])
                original_row.append(row['C'])
                
                row_data.append(row['D'])
                original_row.append(row['D'])
                
                row_data.append(row['T'])
                original_row.append(row['T'])
                
                # 使用服务层转换好的题型文字描述
                row_data.append(row['type_text'])
                original_row.append(row['type_text'])
                
                # 添加题库分类信息 - 确保转换为整数进行比较
                row_data.append('√' if int(row['LA']) == 1 else '')
                original_row.append(row['LA'])
                
                row_data.append('√' if int(row['LB']) == 1 else '')
                original_row.append(row['LB'])
                
                row_data.append('√' if int(row['LC']) == 1 else '')
                original_row.append(row['LC'])
                
                # 处理图片数据
                row_data.append(row['has_image'])
                original_row.append(row['F'])
                
                # 保存图片数据用于后续显示
                self.image_data.append(row['F'])
                
                data.append(row_data)
                original_data.append(original_row)
            
            # 保存原始数据用于tooltip
            self.original_data = original_data
            
            # 更新表格
            self.sheet.set_sheet_data(data)
            # 保存数据到self.data属性，用于双击编辑功能
            self.data = data
            
            # 设置列宽 - 确保在数据加载后应用
            self.set_column_widths()
            
            # 格式化数字列和截断过长内容
            self.format_columns()
            
            # 更新页码按钮
            self.update_page_buttons()
            
            # 更新总页数
            self.total_pages_label.config(text=str(self.total_pages))
        except Exception as e:
            log_exception(f"加载数据失败: {e}")

    def set_column_widths(self):
        """设置表格列宽 - 确保在数据加载后调用"""
        # 检查self.sheet是否已创建
        if not hasattr(self, 'sheet'):
            return

        # 获取表格框架的宽度
        frame_width = self.table_frame.winfo_width()
        # 如果框架宽度小于最小宽度(600px)，使用默认列宽
        if frame_width < 600:
            for idx, width in enumerate(self.column_widths):
                self.sheet.column_width(column=idx, width=width, only_set_if_too_small=False)
        else:
            # 动态调整列宽，保持比例
            total_default_width = sum(self.column_widths)
            scaling_factor = (frame_width - 40) / total_default_width  # 减去边距
            for idx, width in enumerate(self.column_widths):
                new_width = int(width * scaling_factor)
                self.sheet.column_width(column=idx, width=new_width, only_set_if_too_small=False)
        # 确保表格宽度与框架宽度匹配
        self.sheet.configure(width=frame_width - 20)
    
    def format_columns(self):
        """应用深色主题到表格并截断过长内容"""
        self.sheet.set_options(
            table_bg=self.bg_color,
            table_fg=self.fg_color,
            table_grid_fg=self.grid_color,
            index_bg=self.header_bg,
            index_fg=self.fg_color,
            index_grid_fg=self.grid_color,
            index_selected_cells_bg=self.highlight_color,
            header_bg=self.header_bg,
            header_fg=self.header_fg,
            header_grid_fg=self.grid_color,
            header_selected_cells_bg=self.highlight_color,
            selected_rows_bg=self.highlight_color,
            selected_rows_fg=self.fg_color,
            selected_columns_bg=self.highlight_color,
            selected_cells_bg=self.highlight_color,
            selected_cells_fg=self.fg_color,
            top_left_bg=self.header_bg,
            top_left_fg=self.fg_color,
            top_left_grid_fg=self.grid_color,
            align="center",
            justify="center",
            valign="center",
            cell_justify="center",
            cell_valign="center",
            header_align="center",
            header_justify="center",
            header_valign="center"
        )

        # 设置交替行颜色
        for r in range(len(self.sheet.get_sheet_data())):
            if r % 2 == 1:  # 奇数行
                self.sheet.highlight_rows(
                    rows=r, 
                    bg=self.alt_row_color, 
                    redraw=False
                )
        
        # 截断过长内容并添加省略号
        # 创建一个临时标签来测量文本宽度
        temp_label = ttk.Label(self.root, font=('微软雅黑', 10, 'normal'))
        
        # 获取列宽
        column_widths = [self.sheet.column_width(idx) for idx in range(len(self.columns))]
        
        # 存储哪些单元格被截断
        self.truncated_cells = set()
        
        data = self.sheet.get_sheet_data()
        for r, row in enumerate(data):
            for c, cell_value in enumerate(row):
                # 设置标签文本并测量宽度
                temp_label.config(text=str(cell_value))
                text_width = temp_label.winfo_reqwidth()
                 
                # 如果文本宽度超过列宽的85%，则截断
                if text_width > column_widths[c] * 0.85:
                    # 尝试找到合适的截断点
                    original_text = str(self.original_data[r][c])
                    display_text = original_text
                    
                    # 简单的二分查找来找到最大可显示长度
                    low, high = 0, len(original_text)
                    best_length = 0
                    
                    while low <= high:
                        mid = (low + high) // 2
                        temp_label.config(text=original_text[:mid] + '...')
                        if temp_label.winfo_reqwidth() <= column_widths[c] * 0.85:
                            best_length = mid
                            low = mid + 1
                        else:
                            high = mid - 1
                    
                    if best_length < len(original_text):
                        display_text = original_text[:best_length] + '...'
                        self.truncated_cells.add((r, c))
                    
                    self.sheet.set_cell_data(r, c, display_text)
        
        # 重绘表格
        self.sheet.redraw()

    def change_page_size(self, event=None):
        """改变每页显示数量"""
        try:
            new_size = int(self.page_size_var.get())
            if 1 <= new_size <= 100:
                self.page_size = new_size
                self.current_page = 1
                self.total_pages = ceil(self.total_records / self.page_size)
                self.total_pages_label.config(text=str(self.total_pages))
                self.page_entry.delete(0, tk.END)
                self.page_entry.insert(0, "1")
                self.load_page_data()
        except ValueError:
            log_error("输入错误", "请输入有效的页码数字")

    def go_to_page(self, event=None):
        """跳转到指定页码"""
        try:
            page_num = int(self.page_entry.get())
            if 1 <= page_num <= self.total_pages:
                self.current_page = page_num
                self.load_page_data()
            else:
                self.show_warning("无效页码", f"请输入1到{self.total_pages}之间的页码")
                log_error("无效页码", f"请输入1到{self.total_pages}之间的页码")

        except ValueError:
            self.show_warning("输入错误", "请输入有效的页码数字")
            log_error("输入错误", "请输入有效的页码数字")


    def first_page(self):
        """跳转到首页"""
        if self.current_page != 1:
            self.current_page = 1
            self.page_entry.delete(0, tk.END)
            self.page_entry.insert(0, "1")
            self.load_page_data()

    def prev_page(self):
        """跳转到上一页"""
        if self.current_page > 1:
            self.current_page -= 1
            self.page_entry.delete(0, tk.END)
            self.page_entry.insert(0, str(self.current_page))
            self.load_page_data()

    def next_page(self):
        """跳转到下一页"""
        if self.current_page < self.total_pages:
            self.current_page += 1
            self.page_entry.delete(0, tk.END)
            self.page_entry.insert(0, str(self.current_page))
            self.load_page_data()

    def last_page(self):
        """跳转到末页"""
        if self.current_page != self.total_pages:
            self.current_page = self.total_pages
            self.page_entry.delete(0, tk.END)
            self.page_entry.insert(0, str(self.current_page))
            self.load_page_data()

    def search_data(self, event=None):
        """执行搜索"""
        self.search_query = self.search_var.get().strip()
        
        # 获取分类筛选状态
        filter_la = self.filter_la.get() if hasattr(self, 'filter_la') else False
        filter_lb = self.filter_lb.get() if hasattr(self, 'filter_lb') else False
        filter_lc = self.filter_lc.get() if hasattr(self, 'filter_lc') else False
        
        has_search_or_filter = self.search_query or filter_la or filter_lb or filter_lc
        
        if has_search_or_filter:
            # 从服务层获取搜索结果总数
            try:
                self.total_records = self.service.get_filtered_records_count(
                    search_query=self.search_query,
                    filter_la=filter_la,
                    filter_lb=filter_lb,
                    filter_lc=filter_lc
                )
                self.current_page = 1
                self.page_entry.delete(0, tk.END)
                self.page_entry.insert(0, "1")
                self.total_pages = ceil(self.total_records / self.page_size)
                self.total_pages_label.config(text=str(self.total_pages))
                self.total_records_var.set(f"共 {self.total_records} 题")
            except Exception as e:
                log_error(f"获取搜索结果总数失败: {str(e)}")
                self.show_warning("错误", f"获取搜索结果总数失败: {str(e)}")
        else:
            # 搜索框为空且无分类筛选时，重新加载表格结构
            self.load_table_structure()
            
        # 加载数据
        self.load_page_data()
        
        # 更新页码按钮
        self.update_page_buttons()

    def reset_search(self):
        """重置搜索"""
        self.search_var.set("")
        self.search_query = ""
        # 重置分类筛选
        if hasattr(self, 'filter_la'):
            self.filter_la.set(False)
        if hasattr(self, 'filter_lb'):
            self.filter_lb.set(False)
        if hasattr(self, 'filter_lc'):
            self.filter_lc.set(False)
        self.load_table_structure()
        self.current_page = 1
        self.page_entry.delete(0, tk.END)
        self.page_entry.insert(0, "1")
        self.load_page_data()
        log_debug("搜索已重置，分类筛选已清空")

    def update_page_buttons(self):
        """更新页码列表，使用可点击数字而非按钮"""
        # 清空现有页码
        for widget in self.pages_frame.winfo_children():
            widget.destroy()

        # 计算页码范围
        max_visible_pages = 5
        start_page = max(2, self.current_page - 2)  # 从2开始，因为1会单独显示
        end_page = min(self.total_pages - 1, start_page + max_visible_pages - 1)  # 到total_pages-1结束，因为最后一页会单独显示

        # 调整起始页码以确保显示足够的页码
        if end_page - start_page + 1 < max_visible_pages and end_page < self.total_pages - 1:
            start_page = max(2, end_page - max_visible_pages + 1)

        # 添加第1页
        page_label = ttk.Label(
            self.pages_frame,
            text="1",
            font=('SimHei', 16) if 1 == self.current_page else ('SimHei', 12),
            bootstyle="primary" if self.current_page == 1 else "",
            cursor="hand2"
        )
        page_label.grid(row=0, column=0, padx=2)
        page_label.bind("<Button-1>", lambda e: self.go_to_specific_page(1))
        col = 1

        # 添加前省略号（如果需要）
        if start_page > 2:
            ttk.Label(self.pages_frame, text="...", font=('SimHei', 11)).grid(row=0, column=col, padx=2)
            col += 1

        # 添加中间页码标签（可点击）
        for page_num in range(start_page, end_page + 1):
            # 创建页码标签
            page_label = ttk.Label(
                self.pages_frame,
                text=str(page_num),
                font=('SimHei', 16) if page_num == self.current_page else ('SimHei', 12),
                bootstyle="primary" if page_num == self.current_page else "",
                cursor="hand2"
            )
            page_label.grid(row=0, column=col, padx=2)
            col += 1

            # 绑定点击事件
            page_label.bind("<Button-1>", lambda e, p=page_num: self.go_to_specific_page(p))

        # 添加后省略号（如果需要）
        if end_page < self.total_pages - 1:
            ttk.Label(self.pages_frame, text="...", font=('SimHei', 11)).grid(row=0, column=col, padx=2)
            col += 1

        # 添加最后一页
        if self.total_pages > 1:
            page_label = ttk.Label(
                self.pages_frame,
                text=str(self.total_pages),
                font=('SimHei', 12),
                bootstyle="primary" if self.current_page == self.total_pages else "",
                cursor="hand2"
            )
            page_label.grid(row=0, column=col, padx=2)
            page_label.bind("<Button-1>", lambda e: self.go_to_specific_page(self.total_pages))

    def go_to_specific_page(self, page_num):
        """跳转到指定页码"""
        if 1 <= page_num <= self.total_pages:
            self.current_page = page_num
            self.page_entry.delete(0, tk.END)
            self.page_entry.insert(0, str(self.current_page))
            self.load_page_data()

    def show_warning(self, title, message):
        """显示警告对话框"""
        CustomMessageBox.showwarning(title, message, parent=self.root.winfo_toplevel())

    def show_info(self, title, message):
        """显示信息对话框"""
        CustomMessageBox.showinfo(title, message, parent=self.root.winfo_toplevel())
        
    def show_confirm(self, title, message):
        """显示确认对话框"""
        return CustomMessageBox.askyesno(title, message, parent=self.root.winfo_toplevel())


    def on_cell_click(self, event):
        """处理单元格点击事件 - 用于图片查看"""
        region = self.sheet.identify_region(event)
        row = self.sheet.identify_row(event)
        col = self.sheet.identify_column(event)

        log_debug(f"on_cell_click: 点击了第{row}行第{col}列")
        
        # 检查是否点击了图片列（索引为11）
        if region == "table" and col == 11 and hasattr(self, 'image_data') and 0 <= row < len(self.image_data):
            image_data = self.image_data[row]
            if image_data and isinstance(image_data, str) and image_data.startswith('data:image/'):
                # 提取base64图片数据
                import base64
                from io import BytesIO
                
                try:
                    # 去除前缀
                    img_data = image_data.split(',')[1]
                    # 解码base64
                    decoded_data = base64.b64decode(img_data)
                    # 创建图片
                    img = Image.open(BytesIO(decoded_data))
                    
                    # 关闭已存在的图片窗口
                    if self.image_window is not None:
                        self.image_window.destroy()
                    
                    # 使用根窗口作为父窗口引用
                    # 添加额外的update_idletasks确保获取最新位置
                    self.root.update_idletasks()
                    topLevel = self.root.winfo_toplevel()

                    parent_x = topLevel.winfo_x()
                    parent_y = topLevel.winfo_y()
                    parent_width = topLevel.winfo_width()
                    parent_height = topLevel.winfo_height()

                    # 创建新窗口显示图片
                    # 创建透明遮罩层
                    self.mask = tk.Toplevel(self.root)
                    self.mask.overrideredirect(True)
                    self.mask.attributes('-alpha', 0.3)
                    self.mask.geometry(f'{parent_width+5}x{parent_height+35}+{parent_x+5}+{parent_y}')
                    self.mask.configure(bg='black')
                    
                    # 确保遮罩层在所有窗口下方，但在主窗口上方
                    self.mask.attributes('-topmost', False)
                    self.mask.lift(self.root)
                    
                    # 点击遮罩层关闭图片窗口
                    self.mask.bind('<Button-1>', lambda e: self.on_image_window_close())
                    
                    # 创建图片窗口
                    self.image_window = tk.Toplevel(self.root)
                    # 移除标题栏
                    self.image_window.overrideredirect(True)
                    
                    # 确保图片窗口在最上方
                    self.image_window.attributes('-topmost', True)
                    self.image_window.lift(self.mask)
                    
                    # 计算窗口在父窗口中心的位置
                    # 先设置窗口尺寸
                    self.image_window.geometry(f"{img.width}x{img.height}")
                     
                    # 确保窗口尺寸已计算
                    self.image_window.update_idletasks()
                    
                    window_width = self.image_window.winfo_width()
                    window_height = self.image_window.winfo_height()
                     
                    # 计算并设置窗口位置
                    x = parent_x + (parent_width - window_width) // 2
                    y = parent_y + (parent_height - window_height) // 2
                    
                    # 如果计算位置为负数或0，使用默认偏移
                    if x <= 0: x = 50
                    if y <= 0: y = 50

                    # log_info(f"父窗口位置: {parent_x}, {parent_y}")
                    # log_info(f"父窗口尺寸: {parent_width}x{parent_height}")
                    # log_info(f"图片窗口尺寸: {window_width}x{window_height}")
                    # log_info(f"计算位置: {x}x{y}")
                    # log_info(f"图片窗口位置: {img.width}x{img.height}+{x}+{y}")


                    self.image_window.geometry(f"{img.width}x{img.height}+{x}+{y}")
                    
                    # 添加右键菜单以关闭窗口
                    self.create_image_window_menu()
                    
                    # 当窗口关闭时重置引用
                    self.image_window.protocol("WM_DELETE_WINDOW", self.on_image_window_close)
                    
                    # 转换为PhotoImage
                    photo = ImageTk.PhotoImage(img)
                    
                    # 创建标签显示图片
                    img_label = ttk.Label(self.image_window, image=photo)
                    img_label.image = photo  # 保持引用
                    img_label.pack()
                except Exception as e:
                    log_error(f"图片加载失败: {str(e)}")
                      
    def on_row_double_click(self, event):
        """处理行双击事件 - 用于数据编辑"""
        region = self.sheet.identify_region(event)
        row = self.sheet.identify_row(event)
        col = self.sheet.identify_column(event)

        # 添加调试信息
        log_debug(f"双击事件: 区域={region}, 行={row}, 列={col}")

        # 确保点击的是表格区域内的单元格
        if region == "table" and hasattr(self, 'data') and self.data is not None:
            # 注意：ttk.Treeview的行索引从0开始
            if 0 <= row < len(self.data):
                # 获取当前行数据
                row_data = self.data[row]
                # 创建编辑窗口
                self.create_edit_window(row, row_data)
            else:
                log_debug(f"行索引超出范围: {row}, 数据长度: {len(self.data)}")
        else:
            if not hasattr(self, 'data'):
                log_debug("没有data属性")
            elif self.data is None:
                log_debug("data属性为None")
            else:
                log_debug(f"点击区域不是表格: {region}")
        
    def create_edit_window(self, row_index, row_data):
        """创建编辑窗口，使用原始数据库数据"""
        # 关闭已存在的编辑窗口
        if hasattr(self, 'edit_window') and self.edit_window is not None:
            self.edit_window.destroy()

        # 创建新窗口
        # 使用根窗口作为父窗口引用
        self.edit_window = tk.Toplevel(self.root)
        self.edit_window.title("编辑数据")
        width = WINDOW_CONFIG['edit_window']['width']
        height = WINDOW_CONFIG['edit_window']['height']
        self.edit_window.geometry(f"{width}x{height}")
        self.edit_window.resizable(True, True)

        # 确保获取最新的父窗口位置和尺寸
        self.root.update_idletasks()
        top_level = self.root.winfo_toplevel()
        top_level.update_idletasks()
        
        # 计算父窗口位置和尺寸
        parent_x = top_level.winfo_x()
        parent_y = top_level.winfo_y()
        parent_width = top_level.winfo_width()
        parent_height = top_level.winfo_height()
        
        # 计算编辑窗口尺寸
        window_width = 800
        window_height = 650
        
        # 计算居中位置
        x = parent_x + (parent_width - window_width) // 2
        y = parent_y + (parent_height - window_height) // 2
        
        # 如果计算位置为负数或0，使用默认偏移
        if x <= 0: x = 50
        if y <= 0: y = 50
        
        # 设置窗口位置
        self.edit_window.geometry(f"800x650+{x}+{y}")

        # 窗口初始时置顶，但允许其他窗口覆盖
        self.edit_window.attributes('-topmost', False)

        # 创建框架
        frame = ttk.Frame(self.edit_window)
        frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)

        # 创建内容框架
        content_frame = ttk.Frame(frame)
        content_frame.pack(fill=tk.BOTH, expand=True)
        # 设置列权重，使第二列(输入框所在列)能够随窗口宽度变化而扩展
        content_frame.columnconfigure(1, weight=1)

        # 移除滚动条相关引用
        self.edit_canvas = None
        self.edit_scrollbar = None

        # 存储输入框的引用
        self.edit_entries = {}
        self.current_edit_row = row_index

        # 获取列名和原始数据
        columns = getattr(self, 'columns', ['id', 'Q', 'A', 'B', 'C', 'D', 'T', 'type', 'LA', 'LB', 'LC', 'F'])
        if hasattr(self, 'original_data') and 0 <= row_index < len(self.original_data):
            original_row_data = self.original_data[row_index]
        else:
            original_row_data = row_data

        # 创建标签和输入框
        row_num = 0  # 用于跟踪当前行号
        for i, (col_name, value) in enumerate(zip(columns, original_row_data)):
            # 跳过id字段
            if col_name == 'id':
                continue
                
            # 特殊处理图片列
            if col_name == 'F':
                ttk.Label(content_frame, text="图片:", font=('SimHei', 10)).grid(row=row_num, column=0, sticky=tk.W, pady=5, padx=5)
                
                # 图片显示区域
                img_frame = tk.Frame(content_frame, width=200, height=150, relief=tk.SUNKEN, borderwidth=0)
                img_frame.grid(row=row_num, column=1, pady=5, padx=5, sticky=tk.NW)
                img_frame.grid_propagate(False)
                
                # 初始化图片标签
                self.img_label = ttk.Label(img_frame, text="点击更改图片")
                self.img_label.pack(fill=tk.BOTH, expand=True)
                
                # 存储图片数据
                self.current_image_data = value
                
                # 保存img_frame引用
                self.img_frame = img_frame
                
                # 如果有图片数据，显示图片
                if value and isinstance(value, str) and value.startswith('data:image/'):
                    try:
                        import base64
                        from io import BytesIO
                        
                        # 提取base64图片数据
                        img_data = value.split(',')[1]
                        # 解码base64
                        decoded_data = base64.b64decode(img_data)
                        # 创建图片
                        img = Image.open(BytesIO(decoded_data))
                        
                        # 调整图片大小以适应显示区域
                        img.thumbnail((200, 150), Image.Resampling.LANCZOS)
                        
                        # 转换为PhotoImage
                        photo = ImageTk.PhotoImage(img)
                        
                        # 更新标签
                        self.img_label.config(image=photo, text="")
                        self.img_label.image = photo  # 保持引用
                    except Exception as e:
                        log_error(f"加载图片时出错: {e}")
                        self.img_label.config(text="图片加载失败")

                    # 创建删除按钮
                    self.create_delete_button()
                
                # 绑定点击事件以选择图片
                img_frame.bind('<Button-1>', lambda e: self.select_new_image())
                self.img_label.bind('<Button-1>', lambda e: self.select_new_image())
                # 确保事件冒泡
                img_frame.bind('<Button-1>', lambda e: 'break')
                
                # 增加行号
                row_num += 1
            # 特殊处理type字段（单选题/多选题）- 现在自动判断，不再显示UI
            elif col_name == 'type':
                # 存储类型值但不创建UI元素
                try:
                    type_value = int(value) if value else 1
                except ValueError:
                    type_value = 1 if str(value) == '单选' else 2 if str(value) == '多选' else 1
                
                self.type_var = tk.IntVar(value=type_value)
                self.edit_entries[i] = self.type_var
                # 不增加行号，因为没有UI元素
            # 特殊处理LA、LB、LC字段（复选框）
            elif col_name == 'LA':
                # 存储复选框值
                la_var = tk.BooleanVar(value=bool(int(value)) if value else False)
                
                # 保存到edit_entries
                self.edit_entries[i] = la_var
            elif col_name == 'LB':
                # 存储复选框值
                lb_var = tk.BooleanVar(value=bool(int(value)) if value else False)
                
                # 保存到edit_entries
                self.edit_entries[i] = lb_var
            elif col_name == 'LC':
                # 存储复选框值
                lc_var = tk.BooleanVar(value=bool(int(value)) if value else False)
                
                # 保存到edit_entries
                self.edit_entries[i] = lc_var
                
                # 在LC列处理完毕后，将所有分类复选框放在同一行
                if col_name == 'LC':
                    # 创建分类标签
                    ttk.Label(content_frame, text="分类:", font=('SimHei', 10)).grid(row=row_num, column=0, sticky=tk.W, pady=5, padx=5)
                    
                    # 创建复选框框架
                    checkbox_frame = ttk.Frame(content_frame)
                    checkbox_frame.grid(row=row_num, column=1, sticky=tk.W, pady=5, padx=5)
                    
                    # 创建A类复选框
                    ttk.Checkbutton(checkbox_frame, text="A类", variable=la_var).pack(side=tk.LEFT, padx=10)
                    
                    # 创建B类复选框
                    ttk.Checkbutton(checkbox_frame, text="B类", variable=lb_var).pack(side=tk.LEFT, padx=10)
                    
                    # 创建C类复选框
                    ttk.Checkbutton(checkbox_frame, text="C类", variable=lc_var).pack(side=tk.LEFT, padx=10)
                    
                    # 增加行号
                    row_num += 1
            elif col_name == 'T':
                    # 正确答案使用复选框
                    ttk.Label(content_frame, text="正确答案:", font=('SimHei', 10)).grid(row=row_num, column=0, sticky=tk.W, pady=5, padx=5)
                    
                    # 创建复选框框架
                    answer_frame = ttk.Frame(content_frame)
                    answer_frame.grid(row=row_num, column=1, sticky=tk.W, pady=5, padx=5)
                    
                    # 存储复选框值
                    self.answer_vars = {
                        'A': tk.BooleanVar(value='A' in str(value) if value else False),
                        'B': tk.BooleanVar(value='B' in str(value) if value else False),
                        'C': tk.BooleanVar(value='C' in str(value) if value else False),
                        'D': tk.BooleanVar(value='D' in str(value) if value else False)
                    }
                    
                    # 创建复选框
                    ttk.Checkbutton(answer_frame, text="A", variable=self.answer_vars['A']).pack(side=tk.LEFT, padx=10)
                    ttk.Checkbutton(answer_frame, text="B", variable=self.answer_vars['B']).pack(side=tk.LEFT, padx=10)
                    ttk.Checkbutton(answer_frame, text="C", variable=self.answer_vars['C']).pack(side=tk.LEFT, padx=10)
                    ttk.Checkbutton(answer_frame, text="D", variable=self.answer_vars['D']).pack(side=tk.LEFT, padx=10)
                    
                    # 保存引用
                    self.edit_entries[i] = self.answer_vars
                    
                    # 增加行号
                    row_num += 1
            else:
                # 根据列名显示对应的表格标题
                column_titles = {
                    'id': 'ID',
                    'Q': '题目',
                    'A': '选项A',
                    'B': '选项B',
                    'C': '选项C',
                    'D': '选项D'
                }
                label_text = column_titles.get(col_name, col_name) + ':'
                
                # 标签
                ttk.Label(content_frame, text=label_text, font=('SimHei', 10)).grid(row=row_num, column=0, sticky=tk.W, pady=5, padx=5)
                
                # 对于长文本使用Text组件
                text_frame = ttk.Frame(content_frame)
                text_frame.grid(row=row_num, column=1, sticky=tk.EW, pady=5, padx=5)
                
                # 设置text_frame的列权重，使其适应编辑窗口宽度
                text_frame.columnconfigure(0, weight=1)
                
                # 创建Text组件，宽度设为0以自适应父容器，高度自适应内容
                text_widget = tk.Text(text_frame, wrap=tk.WORD, width=0)
                
                # 计算并设置初始高度
                # 已在上方插入内容并设置高度，此处不再重复
                line_count = max(1, text_widget.get('1.0', 'end').count('\n'))
                text_widget.configure(height=line_count)
                
                # 绑定事件以在内容变化时更新高度
                def update_height(event):
                    line_count = max(1, text_widget.get('1.0', 'end').count('\n'))
                    text_widget.configure(height=line_count)
                
                text_widget.bind('<KeyRelease>', update_height)
                text_widget.insert(tk.END, str(value) if value is not None else '')
                text_widget.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
                
                # 添加滚动条
                text_scrollbar = ttk.Scrollbar(text_frame, orient=tk.VERTICAL, command=text_widget.yview)
                text_scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
                text_widget.configure(yscrollcommand=text_scrollbar.set)
                
                # 保存引用
                self.edit_entries[i] = text_widget
                
                # 增加行号
                row_num += 1

        # 按钮框架
        button_frame = ttk.Frame(self.edit_window)
        button_frame.pack(fill=tk.X, padx=10, pady=10)

        # 保存按钮
        save_btn = ttk.Button(button_frame, text="保存", command=lambda: self.save_edited_data(row_index))
        save_btn.pack(side=tk.RIGHT, padx=5)

        # 取消按钮
        cancel_btn = ttk.Button(button_frame, text="取消", command=self.close_edit_window)
        cancel_btn.pack(side=tk.RIGHT, padx=5)

    def create_delete_button(self):
        """创建删除图片按钮"""
        # 先移除已存在的删除按钮
        if hasattr(self, 'delete_btn') and self.delete_btn is not None:
            self.delete_btn.destroy()
            delattr(self, 'delete_btn')
            if hasattr(self.img_frame, 'remove_photo'):
                delattr(self.img_frame, 'remove_photo')

        # 加载删除图标
        remove_icon_path = resource_path(os.path.join("icon", "remove.png"))
        if os.path.exists(remove_icon_path):
            remove_img = Image.open(remove_icon_path)
            remove_img = remove_img.resize((25, 25), Image.Resampling.LANCZOS)
            remove_photo = ImageTk.PhotoImage(remove_img)
        else:
            remove_photo = None

        # 创建标签作为删除按钮
        self.delete_btn = ttk.Label(
            self.img_frame,
            image=remove_photo,
            cursor="hand2"
        )
        # 放置在右上角
        self.delete_btn.place(relx=1.0, rely=0.0, anchor='ne', x=-5, y=5)
        # 绑定点击事件
        self.delete_btn.bind("<Button-1>", lambda e: self.delete_image())
        # 保存引用以防止图片被垃圾回收
        self.img_frame.remove_photo = remove_photo
        # 确保按钮在图片上方显示
        self.delete_btn.lift()

    def delete_image(self):
        """删除当前图片"""
        # 确认是否删除图片
        if self.show_confirm("确认删除", "确定要删除当前图片吗？"):
            # 清除图片数据
            self.current_image_data = None
            
            # 重置图片标签
            self.img_label.config(image="", text="点击更改图片")
            
            # 如果有图片引用，清除它
            if hasattr(self.img_label, 'image'):
                delattr(self.img_label, 'image')
            
            # 移除删除按钮
            if hasattr(self, 'delete_btn') and self.delete_btn is not None:
                self.delete_btn.destroy()
                delattr(self, 'delete_btn')
                if hasattr(self.img_frame, 'remove_photo'):
                    delattr(self.img_frame, 'remove_photo')
        
    def select_new_image(self):
        """选择新图片"""
        from tkinter import filedialog
        
        # 打开文件选择对话框，指定父窗口为编辑窗口
        file_path = filedialog.askopenfilename(
            filetypes=[("图片文件", "*.png;*.jpg;*.jpeg;*.gif;*.bmp")],
            parent=self.edit_window  # 确保对话框出现在编辑窗口上方
        )
        
        # 文件选择对话框关闭后，确保编辑窗口在主窗口上方
        self.edit_window.lift(self.root)
        
        if file_path:
            try:
                # 读取图片文件
                with open(file_path, 'rb') as f:
                    image_data = f.read()
                
                # 转换为base64
                import base64
                base64_data = base64.b64encode(image_data).decode('utf-8')
                
                # 获取文件扩展名
                import os
                file_ext = os.path.splitext(file_path)[1].lower()
                if file_ext == '.png':
                    img_format = 'png'
                elif file_ext in ['.jpg', '.jpeg']:
                    img_format = 'jpeg'
                elif file_ext == '.gif':
                    img_format = 'gif'
                elif file_ext == '.bmp':
                    img_format = 'bmp'
                else:
                    img_format = 'png'  # 默认使用png
                
                # 构建data URL
                data_url = f"data:image/{img_format};base64,{base64_data}"
                
                # 更新当前图片数据
                self.current_image_data = data_url
                
                # 显示新图片
                from io import BytesIO
                img = Image.open(BytesIO(base64.b64decode(base64_data)))
                img.thumbnail((200, 150), Image.Resampling.LANCZOS)
                photo = ImageTk.PhotoImage(img)
                
                self.img_label.config(image=photo, text="")
                self.img_label.image = photo  # 保持引用
                
                # 创建删除按钮
                self.create_delete_button()
            except Exception as e:
                log_error(f"更新图片时出错: {e}")
                self.show_warning("错误", f"更新图片时出错: {str(e)}")

    # 已移除拖放图片功能
    # def handle_image_drop(self, event):
    #     """处理拖放的图片"""
    #     pass

    def save_edited_data(self, row_index):
        """保存编辑后的数据到数据库"""
        import time
        start_time = time.time()
        log_debug("开始保存数据...")
        if hasattr(self, 'edit_window') and self.edit_window is not None:
            try:
                # 获取编辑后的数据
                edited_data = []
                columns = getattr(self, 'columns', ['id', 'Q', 'A', 'B', 'C', 'D', 'T', 'type', 'LA', 'LB', 'LC', 'F'])
                original_row_data = self.original_data[row_index] if hasattr(self, 'original_data') and 0 <= row_index < len(self.original_data) else []
                
                # 初始化edited_data为原始数据的副本
                if len(original_row_data) == len(columns):
                    edited_data = original_row_data.copy()
                else:
                    edited_data = [None] * len(columns)
                
                # 处理每个编辑的字段
                for i in sorted(self.edit_entries.keys()):
                    # 跳过id字段
                    if columns[i] == 'id':
                        continue
                         
                    # 不同类型的输入组件处理
                    if isinstance(self.edit_entries[i], tk.StringVar):
                        value = self.edit_entries[i].get()
                    elif isinstance(self.edit_entries[i], tk.IntVar):
                        value = self.edit_entries[i].get()
                    elif isinstance(self.edit_entries[i], tk.BooleanVar):
                        value = 1 if self.edit_entries[i].get() else 0
                    elif isinstance(self.edit_entries[i], tk.Text):
                        value = self.edit_entries[i].get("1.0", tk.END).rstrip('\n')
                    elif isinstance(self.edit_entries[i], dict) and columns[i] == 'T':
                        # 处理答案复选框
                        answer_vars = self.edit_entries[i]
                        selected_answers = [k for k, var in answer_vars.items() if var.get()]
                        value = ''.join(selected_answers) if selected_answers else None
                    else:
                        value = str(self.edit_entries[i].get()) if hasattr(self.edit_entries[i], 'get') else str(self.edit_entries[i])
                     
                    # 数据类型转换逻辑
                    if columns[i] in ['LA', 'LB', 'LC']:
                        # 确保是整数
                        try:
                            edited_data[i] = int(value)
                        except ValueError:
                            edited_data[i] = 0
                    elif columns[i] == 'type':
                        # 自动判断题型: 如果答案长度>1则为多选(2)，否则为单选(1)
                        t_index = columns.index('T') if 'T' in columns else -1
                        if t_index != -1 and t_index < len(edited_data) and edited_data[t_index]:
                            edited_data[i] = 2 if len(edited_data[t_index]) > 1 else 1
                        else:
                            edited_data[i] = 1  # 默认单选
                    else:
                        edited_data[i] = value if value else None
                
                # 添加图片数据
                if hasattr(self, 'current_image_data'):
                    # 找到'F'列的索引
                    if 'F' in columns:
                        f_index = columns.index('F')
                        edited_data[f_index] = self.current_image_data
                
                log_debug(f"准备更新数据库，耗时: {time.time() - start_time:.2f}秒")
                
                # 获取id
                id_index = columns.index('id') if 'id' in columns else -1
                if id_index != -1 and id_index < len(edited_data):
                    id_value = edited_data[id_index]
                else:
                    # 从原始数据获取id
                    if len(original_row_data) > 0 and 'id' in columns:
                        id_index_original = columns.index('id')
                        id_value = original_row_data[id_index_original]
                    else:
                        raise ValueError("找不到ID列的值")
                    
                # 构建更新数据字典
                updated_data = {}
                for i, col in enumerate(columns):
                    if col != 'id' and i < len(edited_data):
                        updated_data[col] = edited_data[i]
                        
                # 调用服务层更新数据
                success = self.service.update_question(id_value, updated_data)
                log_debug(f"服务层更新完成，耗时: {time.time() - start_time:.2f}秒")
                
                if not success:
                    raise Exception("服务层更新数据失败")
                
                log_debug(f"开始更新本地数据，耗时: {time.time() - start_time:.2f}秒")
                # 更新本地数据
                if hasattr(self, 'original_data') and 0 <= row_index < len(self.original_data):
                    self.original_data[row_index] = edited_data.copy()
                    
                    # 更新图片数据
                    if 'F' in columns:
                        f_index = columns.index('F')
                        if hasattr(self, 'image_data') and 0 <= row_index < len(self.image_data):
                            self.image_data[row_index] = edited_data[f_index]
                    
                    # 更新表格显示
                    log_debug(f"开始更新表格显示，耗时: {time.time() - start_time:.2f}秒")
                    self.reset_search()
                    log_debug(f"表格显示更新完成，耗时: {time.time() - start_time:.2f}秒")
                    
                # 提示成功
                log_debug(f"准备显示成功提示，耗时: {time.time() - start_time:.2f}秒")
                self.show_info("保存成功", "数据已成功更新到数据库")
                log_debug(f"保存数据完成，总耗时: {time.time() - start_time:.2f}秒")
                
            except Exception as e:
                log_exception(f"保存数据时出错: {e}")
                self.show_warning("保存失败", f"保存数据时出错: {str(e)}")
            finally:
                # 关闭窗口
                self.close_edit_window()

    def close_edit_window(self):
        """关闭编辑窗口"""
        if hasattr(self, 'edit_window') and self.edit_window is not None:
            self.edit_window.destroy()
            self.edit_window = None

    def on_image_window_close(self):
        """当图片窗口关闭时调用"""
        if self.image_window is not None:
            self.image_window.destroy()
            self.image_window = None
        if hasattr(self, 'mask') and self.mask is not None:
            self.mask.destroy()
            delattr(self, 'mask')

    def create_image_window_menu(self):
        """创建图片窗口的右键菜单"""
        if self.image_window is None:
            return

        # 创建菜单
        self.menu = tk.Menu(self.image_window, tearoff=0)
        self.menu.add_command(label="关闭窗口", command=self.on_image_window_close)

        # 绑定右键菜单事件
        def show_menu(event):
            self.menu.post(event.x_root, event.y_root)

        self.image_window.bind("<Button-3>", show_menu)
if __name__ == "__main__":
    root = ttk.Window()
    app = DarkThemeDatabaseApp(root)
    root.mainloop()